package com.egghiro.j2se.game.sace.model.actor;

import com.egghiro.framework.j2se.game.core.SMath;
import com.egghiro.framework.j2se.game.core.model.actor.IActor2D;
import com.egghiro.framework.j2se.game.core.model.actor.ISprite;
import com.egghiro.framework.j2se.game.core.model.actor.Sprite;
import com.egghiro.framework.j2se.game.core.view.SImage;
import com.egghiro.framework.j2se.game.core.view.canvas.SGraphics;
import com.egghiro.framework.j2se.util.IterateRemover;
import com.egghiro.j2se.game.sace.param.SACEConst;
import com.egghiro.j2se.game.sace.state.actorstate.FlyerDoNothingState;
import com.egghiro.j2se.game.sace.state.actorstate.FlyerState;

public abstract class Flyer extends FlyerComponent implements ISprite {
    private Sprite sprite;
    private IActor2D target;
    private FlyerState state = new FlyerDoNothingState(this);
    private long lifeDelay;

    public Flyer(int x, int y, SImage image, IActor2D target) {
        this(x, y, image, target, 0);
    }

    public Flyer(int x, int y, SImage image, IActor2D target, long life) {
        sprite = new Sprite(image, image.getWidth(), image.getHeight());
        this.target = target;
        this.lifeDelay = life;
        this.isAutoRemove = (life > 0);
        sprite.defineReferencePixel(getWidth() / 2, getHeight() / 2);

        defineReferencePixel(getWidth() / 2, getHeight() / 2);
        setRefPixelPosition(x, y);
    }

    @Override
    public void act(IterateRemover itRemover) {
        this.act();
        if (isAutoRemove) {
            lifeDelay -= SACEConst.SLEEP;
            if (lifeDelay <= 0) {
                itRemover.remove();
            }
        }
    }

    @Override
    public void act() {
        state.countDown();
        state.act();
    }

    @Override
    public void paint(SGraphics g) {
        if (isVisible()) {
            g.save();
            g.translate(getRefPixelX(), getRefPixelY());
            g.rotate(SMath.toRadians(state.getAngleInDigree()));

            state.render(g);

            g.restore();
        }
    }

    public IActor2D getTarget() {
        return this.target;
    }

    public void renderAppear(SGraphics g) {
        this.sprite.paint(g);
    }

    public void renderGeneral(SGraphics g) {
        this.sprite.paint(g);
    }

    public void renderDisappear(SGraphics g) {
        this.sprite.paint(g);
    }

    public void setState(FlyerState state) {
        this.state = state;
    }

    public void defineReferencePixel(int rx, int ry) {
        this.sprite.defineReferencePixel(rx, ry);
    }

    public int getHeight() {
        return this.sprite.getHeight();
    }

    public int getRefPixelX() {
        return this.sprite.getRefPixelX();
    }

    public int getRefPixelY() {
        return this.sprite.getRefPixelY();
    }

    public int getRefX() {
        return this.sprite.getRefX();
    }

    public int getRefY() {
        return this.sprite.getRefY();
    }

    public int getWidth() {
        return this.sprite.getWidth();
    }

    public int getX() {
        return this.sprite.getX();
    }

    public int getY() {
        return this.sprite.getY();
    }
    
    public int get2DX(){
        return this.sprite.get2DX();
    }

    public int get2DY(){
        return this.sprite.get2DY();
    }
    
    public boolean isVisible() {
        return this.sprite.isVisible();
    }

    public void setRefPixelPosition(int x, int y) {
        this.sprite.setRefPixelPosition(x, y);
    }

    public void setVisible(boolean visible) {
        this.sprite.setVisible(visible);
    }

    public int getCollidePointX() {
        return this.sprite.getCollidePointX();
    }

    public int getCollidePointY() {
        return this.sprite.getCollidePointY();
    }

    public void move(int dx, int dy) {
        this.sprite.move(dx, dy);
    }

    public void setPosition(int x, int y) {
        this.sprite.setPosition(x, y);
    }

    protected void doSelfDestruction() {
        this.isAutoRemove = true;
        this.lifeDelay = 0;
    }

}
